package com.group7.mall.service.impl;

import com.group7.mall.convert.OrderConverter;
import com.group7.mall.dao.*;
import com.group7.mall.dto.*;
import com.group7.mall.entity.*;
import com.group7.mall.redis.RedissonLock;
import com.group7.mall.req.UserOrderPageRequest;
import com.group7.mall.resp.UserOrderPageResponse;
import com.group7.mall.service.UserOrderService;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;

@Service
public class UserOrderServiceImpl implements UserOrderService {

    @Resource
    private TbUserOrderDao tbUserOrderDao;

    @Resource
    private TbGoodsInventoryPriceDao tbGoodsInventoryPriceDao;

    @Resource
    private TbUserCartDao tbUserCartDao;

    @Resource
    private TbGoodsDao tbGoodsDao;

    @Resource
    private TbCustomerServiceDao tbCustomerServiceDao;

    @Resource
    private TbUserAddressDao tbUserAddressDao;

    @Resource
    private TbSellerDao tbSellerDao;

    @Resource
    private TbUserDao tbUserDao;

    @Resource
    private TbNetProfitDao tbNetProfitDao;

    @Override
    public UserOrderDetailDto showOrderDetail(UserOrderDto userOrderDto) {
        UserOrderDetailDto userOrderDetailDto = OrderConverter.INSTANCE.convertTbUserOrderToUserOrderDetailDto(tbUserOrderDao.queryById(userOrderDto.getOrderId()));
        TbCustomerService tbCustomerService = tbCustomerServiceDao.queryByOrderId(userOrderDto.getOrderId());
        if (tbCustomerService != null) {
            userOrderDetailDto.setServiceId(tbCustomerService.getServiceId());
            userOrderDetailDto.setServiceBeginTime(tbCustomerService.getCreatedTime());
            userOrderDetailDto.setServiceType(tbCustomerService.getServiceType());
        }

        TbUser tbUser = tbUserDao.queryByUserOpenId(userOrderDetailDto.getUserOpenId());
        TbSeller tbSeller = tbSellerDao.queryById(userOrderDetailDto.getStoreId());
        TbGoods tbGoods = tbGoodsDao.queryOrderGoodsById(userOrderDetailDto.getGoodsId());
        if (tbGoods.getIsDeleted() == 0) {
            userOrderDetailDto.setIsDeleted(0);
        } else {
            userOrderDetailDto.setIsDeleted(1);
        }
        userOrderDetailDto.setStoreName(tbSeller.getStoreName());
        userOrderDetailDto.setStoreImage(tbSeller.getStoreImage());
        userOrderDetailDto.setUserName(tbUser.getUsername());
        userOrderDetailDto.setGoodsClass(tbGoods.getGoodsClass());
        userOrderDetailDto.setGoodsImage(tbGoods.getGoodsImage());
        return userOrderDetailDto;
    }

    @Override
    @RedissonLock
    public int refundBeforeShipment(UserOrderDto userOrderDto) {
        TbUserOrder tbUserOrder = tbUserOrderDao.queryById(userOrderDto.getOrderId());
        if (tbUserOrder.getOrderStatus() > 1) {
            return -1;
        }
        Integer combinationId = tbUserOrder.getCombinationId();
        Integer purchaseNumber = tbUserOrder.getPurchaseNumber();
        TbGoodsInventoryPrice tbGoodsInventoryPrice = tbGoodsInventoryPriceDao.queryById(combinationId);
        if(tbGoodsInventoryPrice == null) {
            return 1;
        }
        Integer inventory = tbGoodsInventoryPrice.getInventory();
        // TODO 锁商家发货，若商家已经发货则订单不可取消
        tbGoodsInventoryPrice.setInventory(inventory + purchaseNumber);
        tbUserOrder.setOrderStatus(1);
        tbUserOrder.setIsDeleted(0);
        tbUserOrder.setIsFinished(1);
        tbUserOrder.setFinishedTime(userOrderDto.getFinishedTime());
        tbGoodsInventoryPriceDao.update(tbGoodsInventoryPrice);
        tbUserOrderDao.update(tbUserOrder);
        tbNetProfitDao.deleteByOrderId(userOrderDto.getOrderId());
        return 1;
    }

    @Override
    public int userApplyService(UserOrderDto userOrderDto) {
        // TODO 创建售后订单并给出id
        TbUserOrder tbUserOrder = tbUserOrderDao.queryById(userOrderDto.getOrderId());
        System.out.println(tbUserOrder.toString());
        TbCustomerService tbCustomerService = OrderConverter.INSTANCE.convertTbUserOrderToTbCustomerService(tbUserOrder);
        tbCustomerService.setCreatedTime(userOrderDto.getCreatedTime());
        tbCustomerService.setServiceType(userOrderDto.getServiceType());
        System.out.println(tbCustomerService.toString());
        int i = tbCustomerServiceDao.insert(tbCustomerService);
        tbUserOrder.setServiceId(tbCustomerService.getServiceId());
        tbUserOrder.setOrderStatus(4);
        tbUserOrderDao.update(tbUserOrder);
        return i;
    }

    @Override
    public int userConfirmReceipt(TbUserOrder tbUserOrder) {
        TbUserOrder tbUserOrder1 = tbUserOrderDao.queryById(tbUserOrder.getOrderId());
        TbGoods tbGoods = tbGoodsDao.queryById(tbUserOrder1.getGoodsId());
        Integer combinationId = tbUserOrder.getCombinationId();
        TbGoodsInventoryPrice tbGoodsInventoryPrice = tbGoodsInventoryPriceDao.queryGoodsInventoryByCombinationId2(combinationId);
        if (tbGoodsInventoryPrice != null) {
            tbGoodsInventoryPrice.setPurchaseCount(tbGoodsInventoryPrice.getPurchaseCount() + 1);
            tbGoodsInventoryPriceDao.update(tbGoodsInventoryPrice);
        }
        tbGoods.setTurnover(tbGoods.getTurnover() + tbUserOrder1.getPurchaseNumber());
        tbGoodsDao.update(tbGoods);
        TbNetProfit tbNetProfit = tbNetProfitDao.queryByOrderId(tbUserOrder.getOrderId());
        if (tbNetProfit != null) {
            tbNetProfit.setStatus(1);
            tbNetProfit.setFinishedTime(tbUserOrder.getFinishedTime());
            tbNetProfitDao.update(tbNetProfit);
        }
        return tbUserOrderDao.userConfirmReceipt(tbUserOrder);
    }

    @Override
    public int updateOrderAddress(UserOrderDto userOrderDto) {
        TbUserAddress tbUserAddress = tbUserAddressDao.queryById(userOrderDto.getAddressId());
        userOrderDto.setOrderAddress(tbUserAddress.getAddressLocation() + " " + tbUserAddress.getAddressDetail());
        userOrderDto.setOrderPhone(tbUserAddress.getTelephone());
        userOrderDto.setOrderContactName(tbUserAddress.getContactName());
        return tbUserOrderDao.updateOrderAddress(userOrderDto);
    }

    @Override
    public UserOrderDto createOrderByCart(UserOrderDto userOrderDto) {
        TbUserAddress tbUserAddress = tbUserAddressDao.queryById(userOrderDto.getAddressId());
        userOrderDto.setOrderAddress(tbUserAddress.getAddressLocation() + " " + tbUserAddress.getAddressDetail());
        userOrderDto.setOrderPhone(tbUserAddress.getTelephone());
        userOrderDto.setOrderContactName(tbUserAddress.getContactName());
        TbUserOrder tbUserOrder = OrderConverter.INSTANCE.convertUserOrderDtoToTbUserOrder(userOrderDto);
        tbUserOrder.setOrderLock(1);
        tbUserOrder.setOrderStatus(0);
        tbUserOrder.setIsFinished(0);
        tbUserOrder.setIsDeleted(0);
        Integer cartId = userOrderDto.getCartId();
        TbUserCart tbUserCart = tbUserCartDao.queryById(cartId);
        Integer combinationId = tbUserCart.getCombinationId();
        tbUserOrder.setPurchaseNumber(tbUserCart.getCartNumber());
        TbGoodsInventoryPrice tbGoodsInventoryPrice = tbGoodsInventoryPriceDao.queryById(combinationId);
        tbUserOrder.setOrderPrice(tbGoodsInventoryPrice.getPrice() * tbUserCart.getCartNumber());
        tbUserOrder.setTypeInfo(tbUserCart.getTypeInfo());
        tbUserOrder.setGoodsId(tbUserCart.getGoodsId());
        if (tbGoodsInventoryPrice.getInventory() < tbUserCart.getCartNumber()) {
            return null;
        }
        Integer goodsClass = tbGoodsDao.queryById(tbUserCart.getGoodsId()).getGoodsClass();
        tbUserOrder.setGoodsClass(goodsClass);
        tbUserOrder.setCombinationId(combinationId);
        tbUserOrder.setCreatedTime(userOrderDto.getCreatedTime());
        tbUserOrderDao.insert(tbUserOrder);
        return OrderConverter.INSTANCE.convertTbUserOrderToUserOrderDto(tbUserOrder);
    }

    @Override
    public UserOrderDto createOrderByGoods(UserOrderDto userOrderDto) {
        TbUserAddress tbUserAddress = tbUserAddressDao.queryById(userOrderDto.getAddressId());
        userOrderDto.setOrderAddress(tbUserAddress.getAddressLocation() + " " + tbUserAddress.getAddressDetail());
        userOrderDto.setOrderPhone(tbUserAddress.getTelephone());
        userOrderDto.setOrderContactName(tbUserAddress.getContactName());
        UserCartAddDto userCartAddDto = OrderConverter.INSTANCE.convertUserOrderDtoToUserCartRequest(userOrderDto);
        TbGoodsInventoryPrice tbGoodsInventoryPrice = tbGoodsInventoryPriceDao.queryTbGoodsInventoryPriceByTypesByTypeIds(userCartAddDto);
        TbUserOrder tbUserOrder = OrderConverter.INSTANCE.convertUserOrderDtoToTbUserOrder(userOrderDto);
        tbUserOrder.setOrderLock(1);
        tbUserOrder.setOrderStatus(0);
        tbUserOrder.setIsFinished(0);
        tbUserOrder.setIsDeleted(0);
        Integer number = userOrderDto.getPurchaseNumber();
        tbUserOrder.setOrderPrice(number * tbGoodsInventoryPrice.getPrice());
        Integer combinationId = tbGoodsInventoryPrice.getCombinationId();
        if (tbGoodsInventoryPrice.getInventory() < number) {
            return null;
        }
        Integer goodsClass = tbGoodsDao.queryById(userOrderDto.getGoodsId()).getGoodsClass();
        tbUserOrder.setGoodsClass(goodsClass);
        tbUserOrder.setCombinationId(combinationId);
        tbUserOrder.setCreatedTime(userOrderDto.getCreatedTime());
        tbUserOrderDao.insert(tbUserOrder);
        return OrderConverter.INSTANCE.convertTbUserOrderToUserOrderDto(tbUserOrder);
    }

    @Override
    @RedissonLock
    public int orderAfterPay(UserOrderDto userOrderDto) {
        TbUserOrder tbUserOrder = tbUserOrderDao.queryById(userOrderDto.getOrderId());
        Integer combinationId = tbUserOrder.getCombinationId();
        Integer purchaseNumber = tbUserOrder.getPurchaseNumber();
        TbGoodsInventoryPrice tbGoodsInventoryPrice = tbGoodsInventoryPriceDao.queryById(combinationId);
        if(tbGoodsInventoryPrice == null) {
            return -1;
        }
        Integer inventory = tbGoodsInventoryPrice.getInventory();
        if (inventory < purchaseNumber) {
            return 0;
        }
        tbGoodsInventoryPrice.setInventory(inventory - purchaseNumber);
        tbUserOrder.setOrderStatus(1);
        tbUserOrder.setPayTime(userOrderDto.getPayTime());
        tbGoodsInventoryPriceDao.update(tbGoodsInventoryPrice);
        tbUserOrderDao.update(tbUserOrder);
        TbNetProfit tbNetProfit = new TbNetProfit();
        tbNetProfit.setOrderId(userOrderDto.getOrderId());
        tbNetProfit.setStatus(0);
        tbNetProfit.setStoreId(tbUserOrder.getStoreId());
        tbNetProfit.setValue((tbGoodsInventoryPrice.getPrice() - tbGoodsInventoryPrice.getCostPrice()) * purchaseNumber);
        tbNetProfitDao.insert(tbNetProfit);
        return 1;
    }

    @Override
    public UserOrderPageResponse<UserOrderPreviewDto> showUserOrder(UserOrderPageRequest userOrderPageRequest) {
        userOrderPageRequest.setPageStart((userOrderPageRequest.getPageNo() - 1) * userOrderPageRequest.getPageSize());
        List<TbUserOrder> tbUserOrderList = tbUserOrderDao.queryByLimit(userOrderPageRequest);
        List<UserOrderPreviewDto> userOrderPreviewDtoList = OrderConverter.INSTANCE.convertTbUserOrderListToUserOrderPreviewDtoList(tbUserOrderList);
        userOrderPreviewDtoList.forEach(userOrderPreviewDto -> {
            TbGoods tbGoods = tbGoodsDao.queryOrderGoodsById(userOrderPreviewDto.getGoodsId());
            userOrderPreviewDto.setGoodsImage(tbGoods.getGoodsImage());
            userOrderPreviewDto.setGoodsInfo(tbGoods.getGoodsInfo());
        });
        UserOrderPageResponse<UserOrderPreviewDto> userOrderPageResponse = new UserOrderPageResponse<>();
        userOrderPageResponse.setPageSize(userOrderPageRequest.getPageSize());
        userOrderPageResponse.setCurrent(userOrderPageRequest.getPageNo());
        userOrderPageResponse.setRecords(userOrderPreviewDtoList);
        TbUserOrder tbUserOrder = new TbUserOrder();
        tbUserOrder.setOrderStatus(userOrderPageRequest.getOrderStatus());
        tbUserOrder.setUserOpenId(userOrderPageRequest.getUserOpenId());
        userOrderPageResponse.setTotal(tbUserOrderDao.count(tbUserOrder));
        return userOrderPageResponse;
    }

    @Override
    public int cancelUnpaidOrder(UserOrderDto userOrderDto) {
        return tbUserOrderDao.cancelUnpaidOrder(userOrderDto.getOrderId());
    }

    @RabbitListener(queues = "q.order.dlx")
    public void onMessage(Integer orderId)  {
        TbUserOrder tbUserOrder = tbUserOrderDao.queryById(orderId);
        if (tbUserOrder.getOrderStatus() == 0) {
            tbUserOrder.setIsFinished(1);
            tbUserOrderDao.update(tbUserOrder);
            System.out.println(orderId + " 订单超时未支付已经取消，不信的话就去数据库看看");
        }
    }
}
